﻿using System;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;

using Builderator.Core;
using Builderator.Core.Action;
using Builderator.Core.Interfaces;
using Builderator.Core.Components;

namespace Builderator.Firefly.Controls
{
    public delegate void PropertyChanged(PropertyInfo property, object value);

    public interface IProperty
    {
        event PropertyChanged OnPropertyChanged;
        PropertyInfo Property { get; set; }
    }

    /// <summary>
    /// Interaction logic for ActionControl.xaml
    /// </summary>
    public partial class ActionControl : UserControl
    {
        private ActionControl()
        {
            InitializeComponent();
        }

        public IAction Action
        {
            get;
            set;
        }

        public ActionControl(IAction action)
            : this()
        {
            this.Action = action;

            this.actionNameTextBlock.Text = action.Name;

            this.Build();
        }

        private void Build()
        {
            DocumentProperty attribute;

            foreach (PropertyInfo property in this.Action.GetType().GetProperties())
            {
                if (Attribute.GetCustomAttribute(property, typeof(DocumentProperty), true) == null)
                    continue;

                attribute = (DocumentProperty)Attribute.GetCustomAttribute(property, typeof(DocumentProperty), true);

                if (attribute.Hidden)
                    continue;

                switch (attribute.Type.ToString())
                {
                    case "System.Int32":
                        {
                            IntegerControl integer = new IntegerControl(property);

                            integer.Value = (Int32)property.GetValue(this.Action, null);

                            integer.headerTextBlock.Text = attribute.Name;

                            integer.OnPropertyChanged += new PropertyChanged(property_OnPropertyChanged);

                            this.mainStackPanel.Children.Add(integer);
                        }
                        break;
                    case "System.Boolean":
                        {
                            CheckBoxControl checkBox = new CheckBoxControl(property);

                            checkBox.Checked = (bool)property.GetValue(this.Action, null);

                            checkBox.checkBoxTextBlock.Text = attribute.Name;

                            checkBox.OnPropertyChanged += new PropertyChanged(property_OnPropertyChanged);

                            this.mainStackPanel.Children.Add(checkBox);
                        }
                        break;
                    case "Builderator.Core.TimeInterval":
                        {
                            TimeIntervalControl time = new TimeIntervalControl(property);

                            time.Time = (TimeInterval)property.GetValue(this.Action, null);

                            time.OnPropertyChanged += new PropertyChanged(property_OnPropertyChanged);

                            this.mainStackPanel.Children.Add(time);
                        }
                        break;
                    case "System.Uri":
                        {
                            UriControl uri = new UriControl(property);

                            uri.FileExtensions = attribute.Extensions;

                            uri.headerTextBlock.Text = attribute.Name;

                            uri.Location = (string)property.GetValue(this.Action, null);

                            switch (attribute.BrowseType)
                            {
                                case DocumentProperty.BrowseUriType.File:
                                    uri.Type = UriType.File;
                                    break;
                                case DocumentProperty.BrowseUriType.Folder:
                                    uri.Type = UriType.Folder;
                                    break;
                            }

                            uri.OnPropertyChanged += new PropertyChanged(property_OnPropertyChanged);

                            this.mainStackPanel.Children.Add(uri);
                        }
                        break;
                    case "System.String":
                        {
                            TextControl text = new TextControl(property);

                            text.headerTextBlock.Text = attribute.Name;

                            text.Text = (string)property.GetValue(this.Action, null);

                            text.OnPropertyChanged += new PropertyChanged(property_OnPropertyChanged);

                            if (attribute.Name == "Name")
                            {
                                text.IsReadyOnly = true;

                                this.mainStackPanel.Children.Insert(1, text);
                            }
                            else
                            {
                                this.mainStackPanel.Children.Add(text);
                            }
                        }
                        break;
                    case "Builderator.Core.Action.BuildVersion":
                            {
                                BuildVersionControl version = new BuildVersionControl(property);

                                version.Version = (BuildVersion)property.GetValue(this.Action, null);

                                version.OnPropertyChanged += new PropertyChanged(property_OnPropertyChanged);

                                this.mainStackPanel.Children.Add(version);
                            }
                            break;
                    case "Builderator.Core.VariableDictionary":
                            {
                                VariableControl variables = new VariableControl(property);

                                variables.Variables = (VariableDictionary)property.GetValue(this.Action, null);

                                variables.OnPropertyChanged += new PropertyChanged(property_OnPropertyChanged);

                                this.mainStackPanel.Children.Add(variables);
                            }
                            break;
                    case "Builderator.Core.List":
                            {
                                ListControl list = new ListControl(property);

                                list.headerTextBlock.Text = attribute.Name;

                                list.List = (List)property.GetValue(this.Action, null);

                                list.OnPropertyChanged += new PropertyChanged(property_OnPropertyChanged);

                                this.mainStackPanel.Children.Add(list);
                            }
                            break;
                    case "Builderator.Core.Components.ServerList":
                            {
                                ServerListControl list = new ServerListControl(property);

                                list.headerTextBlock.Text = attribute.Name;

                                list.List = (ServerList)property.GetValue(this.Action, null);

                                list.OnPropertyChanged += new PropertyChanged(property_OnPropertyChanged);

                                this.mainStackPanel.Children.Add(list);
                            }
                            break;
                    default:
                        break;
                }
            }
        }

        private void property_OnPropertyChanged(PropertyInfo property, object value)
        {
            this.Action.GetType().GetProperty(property.Name).SetValue(this.Action, value, null);
        }
    }
}
